home *** CD-ROM | disk | FTP | other *** search
- /* device.c:
- *
- * Handler for ISO-9660 (+ Rock Ridge) + HFS CDROM filing system.
- * Originally based on DOSDEV V1.10 (2 Nov 87) by Matthew Dillon.
- * Major changes made by Nicola Salmoria.
- *
- * ----------------------------------------------------------------------
- * This code is (C) Copyright 1993,1994 by Frank Munkert.
- * All rights reserved.
- * This software may be freely distributed and redistributed for
- * non-commercial purposes, provided this notice is included.
- * ----------------------------------------------------------------------
- * [History removed]
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <exec/resident.h>
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
- #include <dos/filehandler.h>
- #include <devices/timer.h>
- #include <devices/input.h>
- #include <devices/inputevent.h>
- #include <devices/trackdisk.h>
- #include <utility/date.h>
- #include <intuition/intuitionbase.h>
- #include <workbench/workbench.h>
- #include <resources/filesysres.h>
- #include <clib/alib_protos.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/utility.h>
- #include <proto/intuition.h>
- #include <proto/icon.h>
- #include <proto/wb.h>
-
- #include "cdrom.h"
- #include "generic.h"
- #include "rock.h"
-
- #define VERSION 37
- #define REVISION 5
- static const UBYTE versionstring20[] = "\0$VER: amicdfilesystem 37.5 (2.10.94)";
-
-
- /*
- * The only purpose of this Resident structure is to make
- * Version CD0:
- * return the version number of the filesystem.
- */
- static const struct Resident versiontag =
- {
- RTC_MATCHWORD,
- &versiontag,
- &versiontag + 1,
- 0,
- VERSION,
- 0,
- -81,
- NULL,
- &versionstring20[7],
- NULL
- };
-
-
- /* the only global data used is library bases, therefore this code is */
- /* reentrant, and could be run several times. If we added the filesystem */
- /* to the filesystem resource, one instance would be used for multiple */
- /* devices. */
-
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase;
- struct Library *UtilityBase;
- struct IntuitionBase *IntuitionBase;
- struct Library *InputBase;
- struct Library *IconBase;
- struct Library *WorkbenchBase;
-
-
-
- /* global data is kept in the HData structure, instead, which is located */
- /* on the stack. */
-
- struct HConfig
- {
- BOOL UseTrackdisk; /* Use trackdisk calls instead of SCSI-direct */
-
- BOOL Lowercase; /* Map ISO names to lower case */
-
- ULONG ScanInterval; /* Time between successive diskchange checks */
- };
-
- struct HData
- {
- struct MsgPort *MyPort; /* our handler port */
- struct DosList *MyDevNode; /* our device node */
- struct FileSysStartupMsg *fssm;
- struct DosEnvec *envec;
- struct DosList *CurrentVolume; /* current volume, or NULL */
- BPTR LockList; /* list of open locks */
- LONG DiskInserted; /* see #defines below */
- LONG Inhibited; /* !0 if the volume is inhibited (nesting count) */
-
- CDROM *CD;
- VOLUME *CDVolume;
- CDROM_OBJ *TopLevelObj;
-
- UBYTE VolumeName[40]; /* When a dos disk is inserted, contains the */
- /* volume name in BCPL form. */
- /* When an audio disk is inserted, contains */
- /* tha name which will be used for the AppIcon, */
- /* for example CD0:CDDA */
-
- struct AppIcon *AppIcon; /* CDDA AppIcon */
- struct MsgPort *AppPort; /* MsgPort used by the AppIcon */
-
- struct MsgPort *TimerPort; /* timer.device I/O port */
- struct timerequest *TimerIO; /* timer.device I/O request */
- struct IOStdReq *InputIO; /* input.device I/O request */
-
- UBYTE PlayCDDA[128]; /* Command invoked if appicon is activated */
- /* (initialized by Show_CDDA_Icon()) */
- BOOL Playing; /* TRUE if a CDDA disk is playing */
- BOOL pad;
-
- struct HConfig HConfig; /* configuration */
- };
-
-
- /* allowed values for the DiskInserted field */
-
- #define DI_NO_DISK 0 /* no disk in the drive */
- #define DI_DISK_OK 1 /* disk in drive */
- #define DI_UNREADABLE_DISK 2 /* disk in drive, but couldn't be read for some reason */
- #define DI_CDDA_DISK 3 /* CDDA disk in drive */
-
-
-
-
- ULONG Centrypoint(VOID);
-
- VOID ReturnPacket(struct DosPacket *packet,struct MsgPort *port,LONG res1,LONG res2);
- VOID AddToFSResource(ULONG dostype,BPTR seglist);
- void btos(LONG, char *);
- CDROM_OBJ *OpenObject(BPTR parentlock,BSTR name,struct HData *HData);
- BPTR cdlock(CDROM_OBJ *, int,struct HData *HData);
- void cdunlock(BPTR lock,struct HData *HData);
- LONG CheckLock(BPTR lock,struct HData *HData);
- CDROM_OBJ *getlockfile(BPTR lock,struct HData *HData);
- int Check_For_Volume_Name_Prefix (char *);
- VOID Fill_InfoData(struct InfoData *id,struct HData *HData);
- void Fill_FileInfoBlock (struct FileInfoBlock *, CDROM_INFO *, VOLUME *,struct HData *HData);
- void Mount(struct HData *HData);
- struct DosList *CreateVolumeNode(struct HData *HData);
- void RemoveVolumeNode (struct HData *HData);
- VOID RemoveDosList(struct DosList *vol);
- void Check_Disk (struct HData *HData);
- void Send_Timer_Request(struct HData *HData);
- int Open_Timer_Device(struct HData *HData);
- int Open_Input_Device(struct HData *HData);
- VOID CreateInputEvent(BOOL inserted,struct HData *HData);
- int Get_Startup (struct HData *HData);
-
- VOID Display_Error(UBYTE *text,APTR par1, ...);
- VOID Show_CDDA_Icon(struct HData *HData);
- VOID Hide_CDDA_Icon (struct HData *HData);
-
- ULONG _stackswap(ULONG function(),...);
-
-
-
-
- ULONG entrypoint(VOID)
- {
- /* we must always swap the stack because when mounted from RDB we will get */
- /* only 600 bytes of stack. */
- return(_stackswap(Centrypoint));
- }
-
-
-
- ULONG __saveds Centrypoint(VOID)
- {
- struct DosPacket *packet;
- struct Process *process;
- struct HData HData;
- LONG timercount = 0;
-
-
- SysBase = *((struct ExecBase **)4);
-
- process = (struct Process *)FindTask(NULL);
- /* if we were run from a shell, fail */
- if (process->pr_CLI) return(RETURN_FAIL);
-
- WaitPort(&process->pr_MsgPort); /* get startup packet */
- packet = (struct DosPacket *)GetMsg(&process->pr_MsgPort)->mn_Node.ln_Name;
-
- memset(&HData,0,sizeof(struct HData));
-
- if (!(HData.fssm = BADDR(packet->dp_Arg2)) ||
- !(HData.envec = BADDR(HData.fssm->fssm_Environ)) ||
- /* make sure that the mountlist has enough fields */
- HData.envec->de_TableSize < DE_DOSTYPE)
- {
- Forbid();
- ReturnPacket(packet,&process->pr_MsgPort,DOSFALSE,0);
- return(0); /* exit */
- }
-
- HData.MyDevNode = BADDR(packet->dp_Arg3);
-
- /* add the seglist to the filesystem.resource so it will be reused by other */
- /* devices with the same DosType */
- AddToFSResource(HData.envec->de_DosType,HData.MyDevNode->dol_misc.dol_handler.dol_SegList);
-
- if (SysBase->LibNode.lib_Version < 37 ||
- !(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37)) ||
- !(UtilityBase = OpenLibrary("utility.library",37)) ||
- !(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)) ||
- !(HData.MyPort = CreateMsgPort()) ||
- !Open_Timer_Device(&HData) ||
- !Open_Input_Device(&HData) ||
- !Get_Startup(&HData))
- {
- if (DOSBase)
- {
- DeleteMsgPort(HData.MyPort);
- CloseLibrary(IntuitionBase);
- CloseLibrary(UtilityBase);
- CloseLibrary(DOSBase);
- }
- Forbid();
- ReturnPacket(packet,&process->pr_MsgPort,DOSFALSE,0);
- return(0); /* exit */
- }
-
- /* initialize dn_Task so that DOS won't start a new process for every access */
- HData.MyDevNode->dol_Task = HData.MyPort;
-
- ReturnPacket(packet,HData.MyPort,DOSTRUE,0);
-
- Send_Timer_Request(&HData);
-
- Check_Disk(&HData);
-
-
- for (;;)
- {
- ULONG dossignal,appsignal,timersignal,sigrec;
-
-
- dossignal = 1L << HData.MyPort->mp_SigBit;
- appsignal = HData.AppPort ? 1L << HData.AppPort->mp_SigBit : 0;
- timersignal = 1L << HData.TimerPort->mp_SigBit;
-
- sigrec = Wait(dossignal | timersignal | appsignal | SIGBREAKF_CTRL_F);
-
- if (sigrec & SIGBREAKF_CTRL_F)
- {
- D(kprintf("diskchange interrupt!\n"));
- Check_Disk(&HData);
- }
-
- if (sigrec & timersignal)
- {
- if (HData.HConfig.ScanInterval)
- {
- if (++timercount == HData.HConfig.ScanInterval)
- {
- Check_Disk(&HData);
-
- timercount = 0;
- }
- }
-
- /* turn off the motor if it is on (Motor_Off() knows whether it's on) */
- Motor_Off(HData.CD);
-
- /* retry to display the AppIcon, in case something went wrong before */
- if (HData.DiskInserted == DI_CDDA_DISK) Show_CDDA_Icon(&HData);
-
- GetMsg(HData.TimerPort);
- Send_Timer_Request(&HData);
- }
-
- if (sigrec & appsignal)
- {
- struct Message *msg;
-
-
- while (msg = GetMsg(HData.AppPort))
- {
- ReplyMsg (msg);
- if (HData.PlayCDDA[0])
- SystemTags(HData.PlayCDDA,
- SYS_Input,Open("NIL:",MODE_OLDFILE),
- SYS_Output,Open("NIL:",MODE_NEWFILE),
- SYS_Asynch,TRUE,
- TAG_END);
- else
- {
- int res;
-
-
- if (HData.Playing) res = Stop_Play_Audio(HData.CD);
- else res = Start_Play_Audio(HData.CD);
-
- if (res) HData.Playing = !HData.Playing;
- }
- }
- }
-
- if (sigrec & dossignal)
- {
- struct Message *msg;
-
-
- while (msg = GetMsg(HData.MyPort))
- {
- LONG res1,res2;
-
-
- packet = (struct DosPacket *)msg->mn_Node.ln_Name;
-
- switch (packet->dp_Type)
- {
- case ACTION_FINDINPUT:
- case ACTION_FINDUPDATE:
- case ACTION_FINDOUTPUT:
- D(switch (packet->dp_Type)
- {
- case ACTION_FINDUPDATE:
- kprintf("ACTION_FINDUPDATE fh %lx lock %lx name \"%b\" ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3);
- break;
- case ACTION_FINDINPUT:
- kprintf("ACTION_FINDINPUT fh %lx lock %lx name \"%b\" ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3);
- break;
- case ACTION_FINDOUTPUT:
- kprintf("ACTION_FINDOUTPUT fh %lx lock %lx name \"%b\" ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3);
- break;
- }
- )
- res1 = DOSFALSE;
- if (!(res2 = CheckLock(packet->dp_Arg2,&HData)))
- {
- CDROM_OBJ *obj;
-
-
- if (!(obj = OpenObject(packet->dp_Arg2,packet->dp_Arg3,&HData)))
- {
- res2 = IoErr();
- if (res2 == ERROR_OBJECT_NOT_FOUND &&
- packet->dp_Type == ACTION_FINDOUTPUT)
- res2 = ERROR_DISK_WRITE_PROTECTED;
- else if (res2 == TDERR_DiskChanged)
- res2 = packet->dp_Arg2 ? ERROR_DEVICE_NOT_MOUNTED : ERROR_NO_DISK;
- }
- else
- {
- if (packet->dp_Type == ACTION_FINDOUTPUT)
- {
- Close_Object(obj);
- res2 = ERROR_DISK_WRITE_PROTECTED;
- }
- else if (obj->directory_f)
- {
- Close_Object(obj);
- res2 = ERROR_OBJECT_WRONG_TYPE;
- }
- else
- {
- /* make a lock out of the object, this way the icon will not */
- /* disappear from the Workbench if there are files open */
- if (((struct FileHandle *)BADDR(packet->dp_Arg1))->fh_Args =
- cdlock(obj,ACCESS_READ,&HData))
- res1 = DOSTRUE;
- else res2 = ERROR_NO_FREE_STORE;
- }
- }
- }
- break;
-
- case ACTION_FH_FROM_LOCK:
- D(kprintf("ACTION_FH_FROM_LOCK fh %lx lock %lx ->\n",packet->dp_Arg1,packet->dp_Arg2));
- res1 = DOSFALSE;
- if (!(res2 = CheckLock(packet->dp_Arg2,&HData)))
- {
- CDROM_OBJ *obj = getlockfile(packet->dp_Arg2,&HData);
-
-
- if (obj->directory_f)
- res2 = ERROR_OBJECT_WRONG_TYPE;
- else
- {
- ((struct FileHandle *)BADDR(packet->dp_Arg1))->fh_Args = packet->dp_Arg2;
- res1 = DOSTRUE;
- }
- }
- break;
-
- case ACTION_END:
- D(kprintf("ACTION_END fh_Args %lx ->\n",packet->dp_Arg1));
- res1 = DOSFALSE;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- cdunlock(packet->dp_Arg1,&HData);
- res1 = DOSTRUE;
- }
- break;
-
- case ACTION_READ:
- D(kprintf("ACTION_READ fh_Args %lx buffer %lx len %ld ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3));
- res1 = -1;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- res1 = Read_From_File(HData.CDVolume,
- getlockfile(packet->dp_Arg1,&HData),
- (APTR)packet->dp_Arg2,packet->dp_Arg3);
- res2 = IoErr();
- if (res2 == TDERR_DiskChanged)
- res2 = ERROR_DEVICE_NOT_MOUNTED;
-
- if (res1 > 0) res2 = 0;
- }
- break;
-
- case ACTION_SEEK:
- D(kprintf("ACTION_SEEK fh_Args %lx pos %ld offs %ld ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3));
- res1 = -1;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- CDROM_OBJ *obj = getlockfile(packet->dp_Arg1,&HData);
-
-
- res1 = obj->pos;
- if (res2 = Seek_Position(obj,packet->dp_Arg2,packet->dp_Arg3))
- res1 = -1;
- }
- break;
-
- case ACTION_LOCATE_OBJECT:
- D(kprintf("ACTION_LOCATE_OBJECT lock %lx name \"%b\" mode %ld ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3));
- res1 = NULL;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- CDROM_OBJ *obj;
-
-
- if (!(obj = OpenObject(packet->dp_Arg1,packet->dp_Arg2,&HData)))
- {
- res2 = IoErr();
- if (res2 == TDERR_DiskChanged)
- res2 = packet->dp_Arg1 ? ERROR_DEVICE_NOT_MOUNTED : ERROR_NO_DISK;
- }
- else
- {
- if (!(res1 = cdlock(obj,packet->dp_Arg3,&HData)))
- res2 = ERROR_NO_FREE_STORE;
- }
- }
- break;
-
- case ACTION_FREE_LOCK:
- D(kprintf("ACTION_FREE_LOCK lock %lx ->\n",packet->dp_Arg1));
- cdunlock(packet->dp_Arg1,&HData);
- res1 = DOSTRUE;
- break;
-
- case ACTION_COPY_DIR:
- case ACTION_COPY_DIR_FH:
- D(switch (packet->dp_Type)
- {
- case ACTION_COPY_DIR:
- kprintf("ACTION_COPY_DIR lock %lx ->\n",packet->dp_Arg1);
- break;
- case ACTION_COPY_DIR_FH:
- kprintf("ACTION_COPY_DIR_FH fh_Args %lx ->\n",packet->dp_Arg1);
- break;
- }
- )
- res1 = NULL;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)) && packet->dp_Arg1)
- {
- CDROM_OBJ *new;
-
-
- if (!(new = Clone_Object(getlockfile(packet->dp_Arg1,&HData))))
- res2 = ERROR_NO_FREE_STORE;
- else
- {
- if (!(res1 = cdlock(new,ACCESS_READ,&HData)))
- res2 = ERROR_NO_FREE_STORE;
- }
- }
- break;
-
- case ACTION_PARENT:
- case ACTION_PARENT_FH:
- D(switch (packet->dp_Type)
- {
- case ACTION_PARENT:
- D(kprintf("ACTION_PARENT lock %lx ->\n",packet->dp_Arg1));
- break;
- case ACTION_PARENT_FH:
- kprintf("ACTION_PARENT_FH fh_Args %lx ->\n",packet->dp_Arg1);
- break;
- }
- )
- res1 = NULL;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- if (packet->dp_Arg1)
- {
- CDROM_OBJ *obj = getlockfile(packet->dp_Arg1,&HData);
- CDROM_OBJ *parent;
-
-
- if (Is_Top_Level_Object(HData.CDVolume,obj))
- res2 = 0;
- else
- {
- if (!(parent = Find_Parent(HData.CDVolume,obj)))
- {
- res2 = IoErr();
- if (res2 == TDERR_DiskChanged)
- res2 = ERROR_DEVICE_NOT_MOUNTED;
- }
- else
- {
- if (!(res1 = cdlock(parent,ACCESS_READ,&HData)))
- res2 = ERROR_NO_FREE_STORE;
- }
- }
- }
- else
- res2 = ERROR_OBJECT_NOT_FOUND;
- }
- break;
-
- case ACTION_SAME_LOCK: /* Lock Lock Bool */
- {
- CDROM_OBJ *obj1 = getlockfile(packet->dp_Arg1,&HData);
- CDROM_OBJ *obj2 = getlockfile(packet->dp_Arg2,&HData);
- struct FileLock *plock1,*plock2;
-
- D(kprintf("ACTION_SAME_LOCK lock1 %lx lock2 %lx ->\n",packet->dp_Arg1,packet->dp_Arg2));
-
- plock1 = BADDR(packet->dp_Arg1);
- plock2 = BADDR(packet->dp_Arg2);
-
- if (plock1->fl_Volume != plock2->fl_Volume)
- res1 = DOSFALSE;
- else if (Same_Objects(obj1,obj2))
- res1 = DOSTRUE;
- else
- res1 = DOSFALSE;
-
- res2 = 0;
- }
- break;
-
- case ACTION_EXAMINE_OBJECT:
- case ACTION_EXAMINE_FH:
- D(switch (packet->dp_Type)
- {
- case ACTION_EXAMINE_OBJECT:
- kprintf("ACTION_EXAMINE_OBJECT lock %lx fib %lx ->\n",packet->dp_Arg1,packet->dp_Arg2);
- break;
- case ACTION_EXAMINE_FH:
- kprintf("ACTION_EXAMINE_FH fh_Args %lx fib %lx ->\n",packet->dp_Arg1,packet->dp_Arg2);
- break;
- }
- )
- res1 = DOSFALSE;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- struct FileInfoBlock *fib;
- CDROM_INFO info;
-
-
- fib = BADDR(packet->dp_Arg2);
- memset(fib,0,sizeof(struct FileInfoBlock));
- if (!(res2 = CDROM_Info(HData.CDVolume,
- getlockfile(packet->dp_Arg1,&HData),&info)))
- {
- Fill_FileInfoBlock(fib,&info,HData.CDVolume,&HData);
- res1 = DOSTRUE;
- }
- }
- break;
-
- case ACTION_EXAMINE_NEXT:
- D(kprintf("ACTION_EXAMINE_NEXT lock %lx fib %lx (%s) ->\n",packet->dp_Arg1,packet->dp_Arg2,&((struct FileInfoBlock *)BADDR(packet->dp_Arg2))->fib_FileName[1]));
-
- res1 = DOSFALSE;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- struct FileInfoBlock *fib;
- CDROM_OBJ *dir = getlockfile(packet->dp_Arg1,&HData);
- CDROM_INFO info;
-
-
- fib = BADDR(packet->dp_Arg2);
- if (!dir->directory_f)
- res2 = ERROR_OBJECT_WRONG_TYPE;
- else if (res2 = Examine_Next(HData.CDVolume,dir, &info,(unsigned long *)&fib->fib_DiskKey))
- {
- if (res2 == TDERR_DiskChanged)
- res2 = ERROR_DEVICE_NOT_MOUNTED;
- }
- else
- {
- Fill_FileInfoBlock(fib,&info,HData.CDVolume,&HData);
- res1 = DOSTRUE;
- }
- }
- break;
-
- case ACTION_INFO:
- D(kprintf("ACTION_INFO lock %lx infodata %lx ->\n",packet->dp_Arg1,packet->dp_Arg2));
- res1 = DOSFALSE;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- Fill_InfoData(BADDR(packet->dp_Arg2),&HData);
- res1 = DOSTRUE;
- }
- break;
-
- case ACTION_DISK_INFO:
- D(kprintf("ACTION_DISK_INFO infodata %lx ->\n",packet->dp_Arg1));
- Fill_InfoData(BADDR(packet->dp_Arg1),&HData);
- res1 = DOSTRUE;
- break;
-
- case ACTION_CURRENT_VOLUME:
- D(kprintf("ACTION_CURRENT_VOLUME fh_Args %lx ->\n",packet->dp_Arg1));
- if (packet->dp_Arg1)
- res1 = ((struct FileLock *)BADDR(packet->dp_Arg1))->fl_Volume;
- else res1 = MKBADDR(HData.CurrentVolume);
- res2 = HData.fssm->fssm_Unit;
- break;
-
- case ACTION_INHIBIT:
- D(kprintf("ACTION_INHIBIT bool %ld ->\n",packet->dp_Arg1));
- if (packet->dp_Arg1 != DOSFALSE)
- {
- RemoveVolumeNode(&HData);
- HData.Inhibited++;
- HData.DiskInserted = DI_DISK_OK; /* this way any operation */
- /* will fail with error "not a dos disk" */
- }
- else
- {
- if (HData.Inhibited)
- {
- HData.Inhibited--;
- HData.CD->t_changeint2 = (unsigned long)-2;
- HData.DiskInserted = DI_NO_DISK; /* force a disk check */
- Check_Disk(&HData);
- }
- }
- break;
-
- case ACTION_READ_LINK:
- {
- CDROM_OBJ *obj;
- CDROM_OBJ *parentdir = getlockfile (packet->dp_Arg1,&HData);
- char *outbuf = (char *) packet->dp_Arg3;
- t_ulong maxlength = packet->dp_Arg4;
- int offs;
- char buf[256];
- int res;
-
- D(kprintf("ACTION_READ_LINK lock %lx path %s buffer %lx bufsiz %ld ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3,packet->dp_Arg4));
-
- res1 = 0;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- {
- offs = Check_For_Volume_Name_Prefix ((char *) packet->dp_Arg2);
- obj = Open_Object(HData.CDVolume,parentdir, (char *) packet->dp_Arg2 + offs);
- if (obj)
- {
- res = Get_Link_Name (HData.CDVolume,obj, buf, sizeof (buf));
- if (res == 0 || strlen (buf) + HData.VolumeName[0] + 1 >= maxlength)
- strncpy (outbuf, "illegal_link", maxlength - 1);
- else
- {
- if (buf[0] == ':')
- strcpy (outbuf,&HData.VolumeName[0]);
- else
- outbuf[0] = 0;
-
- strcat (outbuf, buf);
- }
-
- outbuf[maxlength - 1] = 0;
- Close_Object(obj);
- res1 = strlen (outbuf);
- }
- else
- {
- res2 = IoErr();
- if (res2 == TDERR_DiskChanged)
- res2 = packet->dp_Arg1 ? ERROR_DEVICE_NOT_MOUNTED : ERROR_NO_DISK;
- }
- }
- }
- break;
-
- case ACTION_RENAME_DISK:
- case ACTION_SERIALIZE_DISK:
- D(switch (packet->dp_Type)
- {
- case ACTION_RENAME_DISK:
- kprintf("ACTION_RENAME_DISK name \"%b\" ->\n",packet->dp_Arg1);
- break;
- case ACTION_SERIALIZE_DISK:
- kprintf("ACTION_SERIALIZE_DISK ->\n");
- break;
- }
- )
- res1 = DOSFALSE;
- if (!HData.CurrentVolume)
- res2 = HData.DiskInserted == DI_NO_DISK ? ERROR_NO_DISK : ERROR_NOT_A_DOS_DISK;
- else res2 = ERROR_DISK_WRITE_PROTECTED;
- break;
-
- case ACTION_FORMAT:
- D(kprintf("ACTION_FORMAT name \"%b\" dostype %lx ->\n",packet->dp_Arg1,packet->dp_Arg2));
- res1 = DOSFALSE;
- if (HData.DiskInserted == DI_NO_DISK) res2 = ERROR_NO_DISK;
- else res2 = ERROR_DISK_WRITE_PROTECTED;
- break;
-
- case ACTION_WRITE:
- case ACTION_SET_FILE_SIZE:
- D(switch (packet->dp_Type)
- {
- case ACTION_WRITE:
- kprintf("ACTION_WRITE fh_Args %lx buffer %lx len %ld ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3);
- break;
- case ACTION_SET_FILE_SIZE:
- kprintf("ACTION_SET_FILE_SIZE fh_Args %lx pos %ld mode %ld ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3);
- break;
- }
- )
- res1 = -1;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- res2 = ERROR_DISK_WRITE_PROTECTED;
- break;
-
- case ACTION_DELETE_OBJECT:
- case ACTION_RENAME_OBJECT:
- case ACTION_CREATE_DIR:
- case ACTION_MAKE_LINK:
- D(switch (packet->dp_Type)
- {
- case ACTION_DELETE_OBJECT:
- kprintf("ACTION_DELETE_OBJECT lock %lx name \"%b\" ->\n",packet->dp_Arg1,packet->dp_Arg2);
- break;
- case ACTION_RENAME_OBJECT:
- kprintf("ACTION_RENAME_OBJECT lock %lx name \"%b\" newlock %lx newname \"%b\" ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3,packet->dp_Arg4);
- break;
- case ACTION_CREATE_DIR:
- kprintf("ACTION_CREATE_DIR lock %lx name \"%b\" ->\n",packet->dp_Arg1,packet->dp_Arg2);
- break;
- case ACTION_MAKE_LINK:
- kprintf("ACTION_MAKE_LINK lock %lx name \"%b\" dest %lx soft %ld ->\n",packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3,packet->dp_Arg4);
- break;
- }
- )
- res1 = DOSFALSE;
- if (!(res2 = CheckLock(packet->dp_Arg1,&HData)))
- res2 = ERROR_DISK_WRITE_PROTECTED;
- break;
-
- case ACTION_SET_PROTECT:
- case ACTION_SET_COMMENT:
- case ACTION_SET_DATE:
- case ACTION_SET_OWNER:
- D(switch (packet->dp_Type)
- {
- case ACTION_SET_PROTECT:
- kprintf("ACTION_SET_PROTECT (arg1 unused) lock %lx name \"%b\" bits %lx ->\n",packet->dp_Arg2,packet->dp_Arg3,packet->dp_Arg4);
- break;
- case ACTION_SET_COMMENT:
- kprintf("ACTION_SET_COMMENT (arg1 unused) lock %lx name \"%b\" comment \"%b\" ->\n",packet->dp_Arg2,packet->dp_Arg3,packet->dp_Arg4);
- break;
- case ACTION_SET_DATE:
- kprintf("ACTION_SET_DATE (arg1 unused) lock %lx name \"%b\" date %lx ->\n",packet->dp_Arg2,packet->dp_Arg3,packet->dp_Arg4);
- break;
- case ACTION_SET_OWNER:
- kprintf("ACTION_SET_OWNER (arg1 unused) lock %lx name \"%b\" owner %lx ->\n",packet->dp_Arg2,packet->dp_Arg3,packet->dp_Arg4);
- break;
- }
- )
- res1 = DOSFALSE;
- if (!(res2 = CheckLock(packet->dp_Arg2,&HData)))
- res2 = ERROR_DISK_WRITE_PROTECTED;
- break;
-
- case ACTION_IS_FILESYSTEM:
- D(kprintf("ACTION_IS_FILESYSTEM ->\n"));
- res1 = DOSTRUE;
- break;
-
- case ACTION_FLUSH:
- D(kprintf("ACTION_FLUSH ->\n"));
- res1 = DOSTRUE;
- break;
-
- default:
- D(kprintf("Unknown pkt #%ld %lx %lx %lx %lx %lx ->\n",(LONG)packet->dp_Type,
- packet->dp_Arg1,packet->dp_Arg2,packet->dp_Arg3,packet->dp_Arg4,packet->dp_Arg5));
- res1 = DOSFALSE;
- res2 = ERROR_ACTION_NOT_KNOWN;
- break;
- }
-
- ReturnPacket(packet,HData.MyPort,res1,res2);
- }
- }
- }
- }
-
-
-
- VOID AddToFSResource(ULONG dostype,BPTR seglist)
- {
- struct FileSysResource *FileSysResBase;
-
-
- if (FileSysResBase = (struct FileSysResource *)OpenResource(FSRNAME))
- {
- struct FileSysEntry *fse,*nfse;
-
-
- Forbid();
-
- fse = (struct FileSysEntry *)FileSysResBase->fsr_FileSysEntries.lh_Head;
- while (nfse = (struct FileSysEntry *)fse->fse_Node.ln_Succ)
- {
- /* if filesystem already in resource, return */
- if (fse->fse_DosType == dostype) break;
-
- fse = nfse;
- }
-
- Permit();
-
- if (!nfse && (fse = AllocMem(sizeof(struct FileSysEntry),MEMF_PUBLIC | MEMF_CLEAR)))
- {
- fse->fse_Node.ln_Name = (UBYTE *)&versionstring20[7];
- fse->fse_DosType = dostype;
- fse->fse_Version = ((LONG)VERSION) << 16 | REVISION;
- fse->fse_PatchFlags = 0x180;
- fse->fse_SegList = seglist;
- fse->fse_GlobalVec = -1;
-
- Forbid();
- AddHead(&FileSysResBase->fsr_FileSysEntries,fse);
- Permit();
- }
- }
- }
-
-
-
- /*
- * Return a packet back to DOS.
- */
- VOID ReturnPacket(struct DosPacket *packet,struct MsgPort *port,LONG res1,LONG res2)
- {
- struct Message *mess;
- struct MsgPort *replyport;
-
-
- D(kprintf("%lx %ld\n",res1,res2));
-
- packet->dp_Res1 = res1;
- packet->dp_Res2 = res2;
- replyport = packet->dp_Port;
- mess = packet->dp_Link;
- packet->dp_Port = port;
- mess->mn_Node.ln_Name = (UBYTE *)packet;
- PutMsg(replyport,mess);
- }
-
-
-
- /*
- * Convert a BSTR into a normal string.. copying the string into buf.
- * I use normal strings for internal storage, and convert back and forth
- * when required.
- */
-
- void btos(LONG bstr, char *buf)
- {
- unsigned char *str = BADDR(bstr);
- memcpy(buf,&str[1],str[0]);
- buf[str[0]] = 0;
- }
-
-
-
- /*
- * Locate and open an object on the CD-ROM. Returns a CDROM_OBJ pointer,
- * or NULL if an error occurred. If an error occurred, IoErr() contains
- * the error code.
- */
- CDROM_OBJ *OpenObject(BPTR parentlock,BSTR name,struct HData *HData)
- {
- CDROM_OBJ *parentdir;
- CDROM_OBJ *obj;
- int offs;
- char buf[256];
-
-
- parentdir = getlockfile(parentlock,HData);
- btos(name,buf);
-
- offs = Check_For_Volume_Name_Prefix(buf);
- if (!buf[offs])
- {
- if (parentdir)
- obj = Clone_Object(parentdir);
- else
- obj = Open_Top_Level_Directory(HData->CDVolume);
- }
- else
- obj = Open_Object(HData->CDVolume,parentdir,buf + offs);
-
- if (obj)
- {
- if (obj->symlink_f)
- {
- Close_Object(obj);
- obj = NULL;
- SetIoErr(ERROR_IS_SOFT_LINK);
- }
- }
- /* else IoErr() already contains the error code set by Open_Object() */
-
- return(obj);
- }
-
-
-
- /*
- * The lock function. The file has already been checked to see if it
- * is lockable given the mode.
- * Returns NULL if out of memory.
- */
-
- BPTR cdlock(CDROM_OBJ *cdfile, int mode,struct HData *HData)
- {
- struct FileLock *lock;
-
-
- if (lock = AllocVec(sizeof(struct FileLock),MEMF_PUBLIC | MEMF_CLEAR))
- {
- lock->fl_Key = (long) cdfile;
- lock->fl_Access = ACCESS_READ;
- lock->fl_Task = HData->MyPort;
- lock->fl_Volume = MKBADDR(HData->CurrentVolume);
-
- lock->fl_Link = HData->LockList;
- HData->LockList = MKBADDR(lock);
- }
-
- return(MKBADDR(lock));
- }
-
-
-
- void cdunlock (BPTR lock,struct HData *HData)
-
- {
- struct FileLock *flock,*cl,*ncl;
- struct DosList *vol;
-
-
- if (!lock) return;
-
- flock = BADDR(lock);
- vol = BADDR(flock->fl_Volume);
- if (vol == HData->CurrentVolume)
- cl = (struct FileLock *)&HData->LockList;
- else
- cl = (struct FileLock *)&vol->dol_misc.dol_volume.dol_LockList;
-
- while (cl && (ncl = BADDR(cl->fl_Link)) != flock) cl = ncl;
-
- if (cl) cl->fl_Link = ncl->fl_Link;
-
- if (vol != HData->CurrentVolume && !vol->dol_misc.dol_volume.dol_LockList)
- {
- RemoveDosList(vol);
- CreateInputEvent(FALSE,HData);
- }
-
- Close_Object(getlockfile(lock,HData));
- FreeVec(flock); /* free lock */
- }
-
-
-
- /*
- * Check if the volume associated to the given lock is present in the drive.
- * Return 0 if everything OK, or an error code (to be assigned to res2) if
- * an error occurred.
- */
- LONG CheckLock(BPTR lock,struct HData *HData)
- {
- if (lock && BADDR(((struct FileLock *)BADDR(lock))->fl_Volume) != HData->CurrentVolume)
- return(ERROR_DEVICE_NOT_MOUNTED);
- else if (!HData->CurrentVolume)
- return(HData->DiskInserted == DI_NO_DISK ? ERROR_NO_DISK : ERROR_NOT_A_DOS_DISK);
- else return(0);
- }
-
-
-
- /*
- * GETLOCKFILE(bptrlock)
- *
- * Return the CDROM_OBJ (file or directory) associated with the
- * given lock, which is passed as a BPTR.
- *
- * According to the DOS spec, the only way a NULL lock will ever be
- * passed to you is if the DosNode->dn_Lock is NULL, but I'm not sure.
- * In anycase, If a NULL lock is passed to me I simply assume it means
- * the root directory of the CDROM.
- */
-
- CDROM_OBJ *getlockfile(BPTR lock,struct HData *HData)
- {
- struct FileLock *rl = BADDR(lock);
-
- if (rl)
- return (CDROM_OBJ *) rl->fl_Key;
- return HData->TopLevelObj;
- }
-
- /*
- * If p_pathname contains a ':' character, return the position of the first
- * character after ':'
- * Otherwise, return 0.
- */
-
- int Check_For_Volume_Name_Prefix (char *p_pathname)
- {
- char *pos = strchr (p_pathname, ':');
-
- return pos ? (pos - p_pathname) + 1 : 0;
- }
-
-
-
- /*
- * Fill an InfoData structure with info on the current volume.
- */
- VOID Fill_InfoData(struct InfoData *id,struct HData *HData)
- {
- memset(id,0,sizeof(struct InfoData));
- id->id_UnitNumber = HData->fssm->fssm_Unit;
- id->id_DiskState = ID_WRITE_PROTECTED;
- if (HData->CurrentVolume)
- {
- id->id_NumBlocks = Volume_Size(HData->CDVolume);
- id->id_NumBlocksUsed = id->id_NumBlocks - Volume_Free(HData->CDVolume);
- D(kprintf("total %ld used %ld\n",id->id_NumBlocks,id->id_NumBlocksUsed));
-
- id->id_DiskType = ID_DOS_DISK;
- id->id_VolumeNode = MKBADDR(HData->CurrentVolume);
- id->id_BytesPerBlock = Block_Size(HData->CDVolume);
- id->id_InUse = HData->LockList;
- }
- else
- {
- if (HData->Inhibited) id->id_DiskType = 0x42555359; /* BUSY */
- else switch (HData->DiskInserted)
- {
- case DI_NO_DISK:
- case DI_CDDA_DISK:
- id->id_DiskType = ID_NO_DISK_PRESENT;
- break;
-
- case DI_UNREADABLE_DISK:
- id->id_DiskType = ID_UNREADABLE_DISK;
- break;
-
- case DI_DISK_OK:
- default:
- id->id_DiskType = ID_NOT_REALLY_DOS;
- break;
- }
- }
- }
-
-
-
- /*
- * Fills a FileInfoBlock with the information contained in the
- * directory record of a CD-ROM directory or file.
- */
-
- void Fill_FileInfoBlock (struct FileInfoBlock *p_fib, CDROM_INFO *p_info, VOLUME *p_volume,struct HData *HData)
- {
- char *src = p_info->name;
- char *dest = p_fib->fib_FileName+1;
- int len = p_info->name_length;
-
-
- if (p_info->symlink_f)
- p_fib->fib_DirEntryType = ST_SOFTLINK;
- else
- p_fib->fib_DirEntryType = p_info->directory_f ? ST_USERDIR : ST_FILE;
-
- p_fib->fib_EntryType = p_fib->fib_DirEntryType;
-
- if (len == 1 && *src == ':')
- {
- /* root of file system: */
- p_fib->fib_DirEntryType = ST_USERDIR;
- /* file name == volume name: */
- /* VolumeName is a BCPL string, but it's NULL-terminated. */
- strcpy(p_fib->fib_FileName,HData->VolumeName);
- }
- else
- {
- short real_len;
-
-
- /* copy file name: */
- memcpy(dest,src,len);
-
- real_len = len;
-
- /* remove version number */
- {
- WORD i;
-
-
- i = len;
- while (i)
- {
- if (src[--i] == ';')
- {
- real_len = i;
- break;
- }
- }
- }
-
- p_fib->fib_FileName[0] = real_len;
- /* NULL terminate the string */
- p_fib->fib_FileName[real_len + 1] = 0;
- }
-
- p_fib->fib_Protection = 0;
- p_fib->fib_Size = p_info->file_length;
- p_fib->fib_NumBlocks = p_info->file_length >> 11;
- if (p_info->symlink_f)
- strcpy (p_fib->fib_Comment, "\x0DSymbolic link");
- else
- p_fib->fib_Comment[0] = 0;
-
- p_fib->fib_Date.ds_Days = p_info->date / (24 * 60 * 60);
- p_fib->fib_Date.ds_Minute = (p_info->date % (24 * 60 * 60)) / 60;
- p_fib->fib_Date.ds_Tick = (p_info->date % 60) * TICKS_PER_SECOND;
- }
-
-
- /*
- * Mount a volume.
- */
-
- void Mount(struct HData *HData)
- {
- Clear_Sector_Buffers(HData->CD); /* make sure the buffers are empty */
-
- HData->CD->t_changeint2 = HData->CD->t_changeint;
- HData->DiskInserted = DI_DISK_OK;
-
- if (!(HData->CDVolume = Open_Volume(HData->CD,
- HData->HConfig.Lowercase)))
- {
- D(kprintf ("!!! cannot open VOLUME !!!\n"));
-
- /* A secondary error less than ERROR_NO_FREE_STORE is supposed to be a device */
- /* error. */
- if (IoErr() < ERROR_NO_FREE_STORE)
- HData->DiskInserted = DI_UNREADABLE_DISK;
-
- if (Has_Audio_Tracks(HData->CD))
- {
- HData->DiskInserted = DI_CDDA_DISK;
- Show_CDDA_Icon(HData);
- }
- CreateInputEvent(TRUE,HData);
- return;
- }
-
- if (!(HData->TopLevelObj = Open_Top_Level_Directory(HData->CDVolume)))
- {
- D(kprintf ("!!! cannot open top level directory !!!\n"));
- Close_Volume(HData->CDVolume);
- HData->CDVolume = NULL;
-
- CreateInputEvent(TRUE,HData);
- return;
- }
-
- D(kprintf ("***mounting***\n"));
-
- Volume_ID(HData->CDVolume,&HData->VolumeName[1],sizeof(HData->VolumeName)-2);
- if (!(HData->VolumeName[0] = strlen(&HData->VolumeName[1])))
- strcpy(HData->VolumeName,"\7Unnamed");
-
- /* if we are (probably) dealing with a floppy, read geometry */
- if (HData->CD->use_trackdisk && !HData->envec->de_LowCyl &&
- Volume_Size(HData->CDVolume) < 10000)
- {
- struct DriveGeometry dg;
-
-
- HData->CD->scsireq->io_Command = TD_GETGEOMETRY;
- HData->CD->scsireq->io_Data = &dg;
- HData->CD->scsireq->io_Length = sizeof(struct DriveGeometry);
- if (!DoIO((struct IORequest *)HData->CD->scsireq))
- {
- HData->envec->de_SizeBlock = dg.dg_SectorSize / 4;
- HData->envec->de_HighCyl = dg.dg_Cylinders - 1;
- HData->envec->de_Surfaces = dg.dg_Heads;
- HData->envec->de_BlocksPerTrack = dg.dg_TrackSectors;
- }
- }
-
- if (!CreateVolumeNode(HData))
- {
- Close_Object(HData->TopLevelObj);
- Close_Volume(HData->CDVolume);
- HData->CDVolume = NULL;
- }
-
- CreateInputEvent(TRUE,HData);
- }
-
-
- /*
- * Create Volume node and add to the device list. This will
- * cause the WORKBENCH to recognize us as a disk. If we don't
- * create a Volume node, Wb will not recognize us.
- */
-
- struct DosList *CreateVolumeNode(struct HData *HData)
- {
- struct DosInfo *di = BADDR(((struct RootNode *)DOSBase->dl_Root)->rn_Info);
- struct DosList *dl;
- ULONG p_volume_date = Volume_Creation_Date(HData->CDVolume);
-
-
- Forbid();
-
- for (dl = BADDR(di->di_DevInfo);dl;dl = BADDR(dl->dol_Next))
- {
- if (dl->dol_Type == DLT_VOLUME &&
- !Stricmp(BADDR(dl->dol_Name),HData->VolumeName) &&
- dl->dol_misc.dol_volume.dol_DiskType == HData->envec->de_DosType &&
- dl->dol_misc.dol_volume.dol_VolumeDate.ds_Days == p_volume_date / (24 * 60 * 60) &&
- dl->dol_misc.dol_volume.dol_VolumeDate.ds_Minute == (p_volume_date % (24 * 60 * 60)) / 60 &&
- dl->dol_misc.dol_volume.dol_VolumeDate.ds_Tick == (p_volume_date % 60) * TICKS_PER_SECOND)
- break;
- }
-
- if (!dl)
- {
- if (dl = MakeDosEntry(&HData->VolumeName[1],DLT_VOLUME))
- {
- dl->dol_misc.dol_volume.dol_DiskType = HData->envec->de_DosType;
- dl->dol_misc.dol_volume.dol_VolumeDate.ds_Days = p_volume_date / (24 * 60 * 60);
- dl->dol_misc.dol_volume.dol_VolumeDate.ds_Minute = (p_volume_date % (24 * 60 * 60)) / 60;
- dl->dol_misc.dol_volume.dol_VolumeDate.ds_Tick = (p_volume_date % 60) * TICKS_PER_SECOND;
- dl->dol_Next = di->di_DevInfo;
- di->di_DevInfo = MKBADDR(dl);
- }
- }
-
- /* make sure that dl_Task is NULL, otherwise it means that another handler */
- /* is using the same disk - we can't create our volume */
- if (dl && !dl->dol_Task)
- {
- struct FileLock *lock;
-
-
- dl->dol_Task = HData->MyPort;
- HData->CurrentVolume = dl;
- HData->LockList = dl->dol_misc.dol_volume.dol_LockList;
- dl->dol_misc.dol_volume.dol_LockList = NULL;
-
- lock = BADDR(HData->LockList);
- while (lock)
- {
- lock->fl_Task = HData->MyPort;
- lock = BADDR(lock->fl_Link);
- }
- }
- else dl = NULL;
-
- Permit();
-
- return(dl);
- }
-
-
-
- /*
- * Remove Volume entry.
- */
-
- void RemoveVolumeNode(struct HData *HData)
- {
- if (HData->DiskInserted != DI_NO_DISK)
- {
- Hide_CDDA_Icon(HData);
- HData->CD->t_changeint2 = HData->CD->t_changeint;
- HData->DiskInserted = DI_NO_DISK;
- HData->Playing = FALSE;
-
- if (HData->CurrentVolume)
- {
- D(kprintf("***unmounting***\n"));
-
- /* remove the volume node only if there are no outstanding locks */
- if (!HData->LockList)
- RemoveDosList(HData->CurrentVolume);
- else
- {
- HData->CurrentVolume->dol_Task = NULL;
- HData->CurrentVolume->dol_misc.dol_volume.dol_LockList = HData->LockList;
- }
-
- Close_Object(HData->TopLevelObj);
- Close_Volume(HData->CDVolume);
-
- HData->CurrentVolume = NULL;
- HData->LockList = NULL;
- HData->CDVolume = NULL;
- }
-
- CreateInputEvent(FALSE,HData);
- }
- }
-
-
-
- VOID RemoveDosList(struct DosList *vol)
- {
- struct DosInfo *di;
- struct DosList *dl;
- void *dlp;
-
-
- D(kprintf("Removing Volume node\n"));
- Forbid ();
-
- di = BADDR(((struct RootNode *)DOSBase->dl_Root)->rn_Info);
-
- dlp = &di->di_DevInfo;
- for (dl = BADDR(di->di_DevInfo);dl && dl != vol;dl = BADDR(dl->dol_Next))
- dlp = &dl->dol_Next;
- if (dl == vol)
- {
- *(BPTR *)dlp = dl->dol_Next;
- FreeDosEntry(dl);
- }
-
- Permit();
- }
-
-
-
- /*
- * Open timer device structures:
- */
-
- int Open_Timer_Device(struct HData *HData)
- {
- if (HData->TimerPort = CreateMsgPort())
- {
- if (HData->TimerIO = (struct timerequest *)
- CreateIORequest(HData->TimerPort,sizeof(struct timerequest)))
- {
- if (!OpenDevice(TIMERNAME,UNIT_VBLANK,HData->TimerIO,0))
- return(1);
-
- DeleteIORequest(HData->TimerIO);
- }
-
- DeleteMsgPort(HData->TimerPort);
- HData->TimerPort = NULL;
- }
-
- return(0);
- }
-
-
-
- /*
- * Open input device structures:
- */
-
- int Open_Input_Device(struct HData *HData)
- {
- struct MsgPort *port;
-
-
- if (port = CreateMsgPort())
- {
- if (HData->InputIO = CreateIORequest(port,sizeof(struct IOStdReq)))
- {
- if (!OpenDevice("input.device",0,HData->InputIO,0))
- {
- InputBase = (struct Library *)HData->InputIO->io_Device;
- return(1);
- }
-
- DeleteIORequest(HData->InputIO);
- }
-
- DeleteMsgPort(port);
- }
-
- return(0);
- }
-
-
-
- /*
- * Send timer request
- */
-
- void Send_Timer_Request(struct HData *HData)
- {
- HData->TimerIO->tr_node.io_Command = TR_ADDREQUEST;
- HData->TimerIO->tr_time.tv_secs = 1;
- HData->TimerIO->tr_time.tv_micro = 0;
- SendIO(HData->TimerIO);
- }
-
-
-
- /*
- * Check whether the disk has been removed or inserted.
- */
-
- void Check_Disk (struct HData *HData)
- {
- int i;
- unsigned long l1, l2;
-
-
- /* don't check for disk if we are inhibited */
- if (HData->Inhibited) return;
-
- D(kprintf ("Checking Disk...\n"));
-
- if (HData->CD->use_trackdisk)
- {
- i = (Test_Unit_Ready(HData->CD));
- l1 = HData->CD->t_changeint;
- l2 = HData->CD->t_changeint2;
- if (l1 != l2)
- {
- if (i)
- {
- D(kprintf ("disk has been inserted (T %ld)\n", l1));
- RemoveVolumeNode(HData);
- Mount(HData);
- }
- else
- {
- if (HData->DiskInserted != DI_NO_DISK)
- {
- D(kprintf ("disk has been removed (T %ld)\n", l1));
- RemoveVolumeNode(HData);
- }
- }
- }
- }
- else
- {
- if (HData->DiskInserted != DI_NO_DISK)
- {
- if (!Test_Unit_Ready(HData->CD))
- {
- D(kprintf ("disk has been removed\n"));
- RemoveVolumeNode(HData);
- }
- }
- else
- {
- /* have to call Test_Unit_Ready() twice because the first SCSI command */
- /* after a disk insertion is always rejected. */
- if (Test_Unit_Ready (HData->CD) || Test_Unit_Ready (HData->CD))
- {
- D(kprintf ("disk has been inserted\n"));
- Mount(HData);
- }
- }
- }
- }
-
-
-
- /*
- * generate a `disk inserted/removed' event, in order to get Workbench to
- * rescan the DosList and update the list of volume icons.
- */
-
- VOID CreateInputEvent(BOOL inserted,struct HData *HData)
- {
- struct InputEvent ie;
-
-
- memset(&ie,0,sizeof(struct InputEvent));
- ie.ie_Class = inserted ? IECLASS_DISKINSERTED : IECLASS_DISKREMOVED;
- HData->InputIO->io_Command = IND_WRITEEVENT;
- HData->InputIO->io_Data = &ie;
- HData->InputIO->io_Length = sizeof(struct InputEvent);
- DoIO(HData->InputIO);
- }
-
-
-
- int
- Get_Startup (struct HData *HData)
- {
- enum {
- ARG_LOWERCASE,
- ARG_TRACKDISK,
- ARG_POLL,
- ARGCOUNT
- };
-
- LONG Args[ARGCOUNT];
- UBYTE *LocalBuffer;
- struct RDArgs *ArgsPtr;
- int result = FALSE,len,i;
- UBYTE *p_startup;
-
-
- /* Clear the argument vector. */
- memset (Args, 0, sizeof(Args));
-
- /* valid startup entry? */
- if (HData->envec->de_TableSize >= DE_CONTROL)
- p_startup = BADDR(HData->envec->de_Control);
- else p_startup = NULL;
-
- if (!p_startup) p_startup = "";
-
- /* Get the contents of the startup field. */
- len = p_startup[0];
- if (!(LocalBuffer = AllocVec(len + 2,MEMF_ANY)))
- return(FALSE);
-
- memcpy (LocalBuffer, p_startup + 1, len);
- /* terminate string with LF (fix ReadArgs() bug) */
- LocalBuffer[len] = '\n';
- /* Provide null-termination. */
- /* Provide null-termination. */
- LocalBuffer[len+1] = 0;
-
- /* Remove leading quotes. */
- for (i = 0 ; i < len ; i++) {
- if (LocalBuffer[i] != ' ') {
- if (LocalBuffer[i] == '\"')
- LocalBuffer[i] = ' ';
- break;
- }
- }
-
- /* Remove trailing quotes. */
- for (i = len - 1 ; i >= 0 ; i--) {
- if (LocalBuffer[i] != ' '){
- if (LocalBuffer[i] == '\"')
- LocalBuffer[i] = ' ';
- break;
- }
- }
-
- if (ArgsPtr = (struct RDArgs *) AllocDosObjectTags (DOS_RDARGS,TAG_DONE))
- {
- /* Don't prompt for input! */
- ArgsPtr->RDA_Flags |= RDAF_NOPROMPT;
-
- /* Set up for local parsing. */
- ArgsPtr->RDA_Source.CS_Buffer = LocalBuffer;
- ArgsPtr->RDA_Source.CS_Length = strlen ((char *) LocalBuffer);
- ArgsPtr->RDA_Source.CS_CurChr = 0;
-
- /* Read the arguments. */
- if (ReadArgs(
- "L=LOWERCASE/S,"
- "T=TRACKDISK/S,"
- "P=POLL/S",
- Args,ArgsPtr))
- {
- result = TRUE;
-
-
- HData->HConfig.Lowercase = Args[ARG_LOWERCASE];
- D(kprintf("lowercase = %ld\n",HData->HConfig.Lowercase));
- HData->HConfig.UseTrackdisk = Args[ARG_TRACKDISK];
- D(kprintf("trackdisk = %ld\n",HData->HConfig.UseTrackdisk));
-
- if (Args[ARG_POLL])
- HData->HConfig.ScanInterval = 3;
- D(kprintf("scaninterval = %ld\n",HData->HConfig.ScanInterval));
-
- FreeArgs(ArgsPtr);
- }
-
- FreeDosObject (DOS_RDARGS, ArgsPtr);
- }
-
- if (result) {
- if (!(HData->CD = Open_CDROM (&((UBYTE *)BADDR(HData->fssm->fssm_Device))[1],
- HData->fssm->fssm_Unit,HData->fssm->fssm_Flags,
- HData->envec->de_LowCyl * HData->envec->de_Surfaces *
- HData->envec->de_BlocksPerTrack * 4 * HData->envec->de_SizeBlock,
- HData->HConfig.UseTrackdisk,
- /* if the Mask is in 24-bit range, use 24BITDMA memory */
- (HData->envec->de_Mask & 0xff000000) ?
- HData->envec->de_BufMemType : HData->envec->de_BufMemType | MEMF_24BITDMA,
- HData->envec->de_NumBuffers,5, /* file buffers */
- !HData->HConfig.ScanInterval))) {
- result = FALSE;
- }
- }
-
- FreeVec(LocalBuffer);
-
- return result;
- }
-
-
-
-
-
-
- VOID Show_CDDA_Icon(struct HData *HData)
- {
- struct DiskObject *appicon;
-
-
- if (!IconBase) IconBase = OpenLibrary("icon.library",37);
- if (!WorkbenchBase) WorkbenchBase = OpenLibrary("workbench.library",37);
-
- if (!IconBase || !WorkbenchBase || HData->AppIcon) return;
-
- if (!(appicon = GetDiskObject("ENV:sys/def_CDDAdisk")) &&
- !(appicon = GetDefDiskObject(WBKICK)))
- return;
-
- strncpy(HData->VolumeName,&((UBYTE *)BADDR(HData->MyDevNode->dol_Name))[1],sizeof(HData->VolumeName)-1);
- if (strlen(HData->VolumeName) < sizeof(HData->VolumeName)-5)
- strcat(HData->VolumeName,":CDDA");
-
- if (HData->AppPort = CreateMsgPort())
- HData->AppIcon = AddAppIconA(0,0,HData->VolumeName,HData->AppPort,NULL,appicon,NULL);
-
- /* copy the default tool name */
- if (appicon->do_DefaultTool)
- strcpy(HData->PlayCDDA,appicon->do_DefaultTool);
- else HData->PlayCDDA[0] = 0;
-
- /* the icon may be freed immediately, the Workbench copies it internally */
- FreeDiskObject(appicon);
-
- /* AddAppIconA may fail if the Workbench has not yet been loaded. */
- if (!HData->AppIcon)
- {
- DeleteMsgPort(HData->AppPort);
- HData->AppPort = NULL;
- }
- }
-
-
-
- void Hide_CDDA_Icon(struct HData *HData)
- {
- struct Message *msg;
-
-
- if (HData->AppIcon)
- {
- RemoveAppIcon(HData->AppIcon);
- HData->AppIcon = NULL;
-
- if (HData->AppPort)
- {
- while (msg = GetMsg(HData->AppPort))
- ReplyMsg(msg);
- DeleteMsgPort(HData->AppPort);
-
- HData->AppPort = NULL;
- }
- }
- }
-